<template>
  <!-- 自定义功能 -->
  <div
    v-loading="loadingState.isLoading"
    class="custom-wrapper"
  >
    <div class="custom-content">
      <a-icon
        class="custom-left-btn base-btn active-btn"
        :class="{'disabled-btn': disabledDirection === 'left'}"
        type="left"
        @click="triggerMove('left')"
      />
      <a-icon
        class="custom-right-btn base-btn"
        :class="{'disabled-btn': disabledDirection === 'right'}"
        type="right"
        @click="triggerMove('right')"
      />
      <div
        class="custom-list"
        @scroll="handleScroll"
      >
        <div
          v-for="item in realCustomList"
          :key="item.id"
          class="custom-item base-btn"
          :title="item.title"
          @click="triggerClick(item)"
        >
          <div
            class="custom-item-icon"
            :style="{ 'backgroundColor': filterColor(item.rootCode).bgColor }"
          >
            <BaseSvgIcon
              :icon="item.rootCode"
              :color="filterColor(item.rootCode).color"
            />
          </div>
          <div class="custom-item-desc text-ellipsis">
            {{ item.title }}
          </div>
        </div>
      </div>
    </div>
    <div class="custom-btns">
      <div
        class="add-btn base-btn"
        @click="visibleState.selectMenu = true"
      >
        <a-icon
          class="add-btn-icon"
          type="plus"
        />
      </div>
      <div class="btn-desc">
        自定义
      </div>
    </div>
    <SelectMenu
      :visible.sync="visibleState.selectMenu"
      :init-checked-keys="customList"
      @confirm="handleConfirmMenu"
    />
  </div>
</template>

<script>
import { useTimer } from '@/utils/util'
import SelectMenu from './SelectMenu'
import { getCustomMenuList, updateCustomMenu } from '@/api/indexPage'
import { getCustomMenuIcon } from '@/utils/util.js'

const COLOR_MAP = {
  'PM': {
    label: '工程',
    color: '#DD4343',
    bgColor: '#FDF4F4'
  },
  'MM': {
    label: '物资',
    color: '#DA6226',
    bgColor: '#FDF5F2'
  },
  'BM': {
    label: '商务',
    color: '#CA8702',
    bgColor: '#FCF8F0'
  },
  'LCM': {
    label: '法务',
    color: '#ADAD00',
    bgColor: '#FAFAEF'
  },
  'QM': {
    label: '质量',
    color: '#78B500',
    bgColor: '#F7FBEF'
  },
  'SHE': {
    label: '安监',
    color: '#42C202',
    bgColor: '#F4FBF0'
  },
  'PMD': {
    label: '设计',
    color: '#03C182',
    bgColor: '#F0FBF7'
  },
  'BIM': {
    label: 'BIM',
    color: '#01ACAC',
    bgColor: '#F0FAFA'
  },
  'STM': {
    label: '科技',
    color: '#0289CA',
    bgColor: '#F0F8FC'
  },
  'TM': {
    label: '技术',
    color: '#386BD0',
    bgColor: '#F3F6FC'
  },
  'BG': {
    label: '办公',
    color: '#5858ED',
    bgColor: '#F5F5FE'
  },
  'thi': {
    label: '事项',
    color: '#8D5BF1',
    bgColor: '#F8F5FE'
  },
  'GH': {
    label: '工会',
    color: '#B024F6',
    bgColor: '#FAF2FE'
  },
  'jijian': {
    label: '纪检',
    color: '#DF21DF',
    bgColor: '#FDF2FD'
  },
  'SYSMG': {
    label: '系统',
    color: '#DC32A3',
    bgColor: '#FDF2FA'
  },
  'DQ': {
    label: '党群',
    color: '#E52D6A',
    bgColor: '#FDF2F6'
  }
}

export default {
  name: 'CustomModule',
  components: {
    SelectMenu
  },
  data() {
    return {
      loadingState: {
        isLoading: true
      },
      visibleState: {
        selectMenu: false
      },
      customList: [],
      disabledDirection: 'left',
    }
  },
  computed: {
    realCustomList() {
      if (this.customList.length) {
        return this.customList
      }
      return [
        {
          id: 'default',
          icon: 'defalut',
          rootCode: 'PM',
          title: '暂无',
          defaultIcon: getCustomMenuIcon('placeholder')
        }
      ]
    }
  },
  created() {
    this.getCustomMenuListReq()
  },
  methods: {
    filterColor(code) {
      return COLOR_MAP[code] || {}
    },
    getMenuIcon(code) {
      return getCustomMenuIcon(code)
    },
    /**
     * 更新自定义的菜单
     */
    async updateCustomMenuReq(list) {
      try {
        if (this.loadingState.isLoading) return
        this.loadingState.isLoading = true
        const params = list.map((item) => {
          const { code, id, title, value, pId } = item
          return {
            resCode: code,
            resId: id,
            resName: title,
            resUrl: value,
            parentId: pId
          }
        })
        await updateCustomMenu(params)
        this.customList = list // 成功之后，将列表替换
      } catch (e) {
        console.error(e)
      }
      this.loadingState.isLoading = false
    },
    /**
     * 获取之前自定义的菜单
     */
    async getCustomMenuListReq() {
      try {
        this.loadingState.isLoading = true
        const params = {
          pageNum: 1,
          pageSize: 99999,
          param: {}
        }
        const res = await getCustomMenuList(params)
        this.customList = (res.data?.list || []).map((item) => {
          const { resFirstCode, resCode, resId, resName, resUrl, parentId } = item
          return {
            ...item,
            rootCode: resFirstCode,
            code: resCode,
            id: resId,
            key: resId,
            title: resName,
            value: resUrl,
            pId: parentId
          }
        })
      } catch (e) {
        console.error(e)
      }
      this.loadingState.isLoading = false
    },
    handleConfirmMenu(list) {
      this.visibleState.selectMenu = false
      this.updateCustomMenuReq(list)
    },
    triggerClick(data) {
      this.$router.push({
        path: data.value
      })
    },
    /**
     * 监听滚动事件，处理按钮的禁用状态
     */
    handleScroll() {
      if(this.scrollTimer) {
        clearTimeout(this.scrollTimer)
        this.scrollTimer = null
      }
      this.scrollTimer = setTimeout(() => {
        const listDom = document.querySelector('.custom-list')
        const clientWidth = listDom.clientWidth
        const scrollWidth = listDom.scrollWidth
        const scrollLeft = listDom.scrollLeft
        if(scrollLeft <= 0) {
          this.disabledDirection = 'left'
        }
        if(scrollLeft > 0 && clientWidth + scrollLeft < scrollWidth) {
          this.disabledDirection = ''
        }

        if(clientWidth + scrollLeft >= scrollWidth) {
          this.disabledDirection = 'right'
        }
      }, 300)
    },
    /**
     * 触发自定义常用功能菜单的移动按钮
     * @param {string} direction 移动的方向   'left' | 'right'
     */
    triggerMove(direction) {
      const listDom = document.querySelector('.custom-list')
      const clientWidth = listDom.clientWidth
      const scrollWidth = listDom.scrollWidth
      const scrollLeft = listDom.scrollLeft
      const offset = (50 + 20) * 2 // 偏移量
      const step = 5 // 移动的步长
      let stepIndex = 1 // 移动的步数
      const [doTimer, cancelTimer] = useTimer()
      if (this.timerId) {
        cancelTimer(this.timerId)
        this.timerId = null
      }
      const actionMap = {
        left: () => {
          if (scrollLeft > 0) {
            doTimer(() => {
              listDom.scrollLeft = scrollLeft - stepIndex * step
              stepIndex++
              // 当移动的总步长小于偏移时，使用定时器循环移动
              if (stepIndex * step < offset) {
                actionMap[direction]()
              }
            })
          } else {
            this.disabledDirection = 'left'
          }
        },
        right: () => {
          if (clientWidth + scrollLeft < scrollWidth) {
            doTimer(() => {
              listDom.scrollLeft = scrollLeft + stepIndex * step
              stepIndex++
              // 当移动的总步长小于偏移时，使用定时器循环移动
              if (stepIndex * step < offset) {
                actionMap[direction]()
              }
            })
          } else {
            this.disabledDirection = 'right'
          }
        }
      }
      actionMap[direction] && actionMap[direction]()
    }
  }
}
</script>

<style lang="less" scoped>
.custom-wrapper {
  height: 121px;
  background: #fff;
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  padding: 0 20px;
  .custom-content {
    flex: 1;
    overflow: hidden;
    margin-right: 10px;
    padding: 0 40px;
    position: relative;
    .custom-list {
      margin-bottom: -18px;
      overflow-x: scroll;
      display: flex;
    }
    .disabled-btn {
      cursor: not-allowed;
      &:active {
        color: #e8e8e8 !important;
      }
    }
    .custom-left-btn {
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      font-size: 28px;
      color: #e8e8e8;
      &:active {
        color: #0389c9;
      }
    }
    .custom-right-btn {
      position: absolute;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
      font-size: 28px;
      color: #e8e8e8;
      &:active {
        color: #0389c9;
      }
    }
    .custom-item {
      flex-shrink: 0;
      margin-right: 50px;
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 60px;
      &:hover {
        color: #0088ec;
        .custom-item-icon {
          box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.16);
        }
      }
      .custom-item-icon {
        width: 100%;
        height: 60px;
        border-radius: 20px;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 26px;
      }
      .custom-item-desc {
        padding-top: 10px;
        text-align: center;
        height: 20px;
        font-size: 12px;
        box-sizing: content-box;
      }
    }
  }
  .custom-btns {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .add-btn {
      width: 50px;
      height: 50px;
      opacity: 1;
      background: #f7fcff;
      border-radius: 20px;
      display: flex;
      justify-content: center;
      align-items: center;
      &:hover {
        box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.16);
      }
      .add-btn-icon {
        font-size: 26px;
        color: #0088ec;
      }
    }
    .btn-desc {
      padding-top: 10px;
    }
  }
}
</style>